<template>
  <div class="upload-container">
    <div class="upload-content">
      <el-upload
        :class="{ limit: props.limit === fileLists.length }"
        class="upload-file"
        :file-list="fileArr"
        ref="uploadRef"
        action="#"
        list-type="picture-card"
        :multiple="multiple"
        :accept="accept"
        :disabled="disabled"
        :auto-upload="false"
        :limit="limit"
        :on-change="onChange"
        :on-exceed="onExceed"
      >
        <el-icon><Plus /></el-icon>
        <template #file="{ file }">
          <template v-if="props.accept.search('image') > -1">
            <div>
              <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
              <span class="el-upload-list__item-actions">
                <span class="el-upload-list__item-preview" @click="onImgPreview(file)">
                  <el-icon><zoom-in /></el-icon>
                </span>
                <!-- <template v-if="props.shear">
                  <span class="el-upload-list__item-preview" @click="onCropper(file)">
                    <el-icon><Crop /></el-icon>
                  </span>
                </template> -->
                <span v-if="!disabled" class="el-upload-list__item-delete" @click="onRemove(file)">
                  <el-icon><Delete /></el-icon>
                </span>
              </span>
            </div>
          </template>
          <template v-else>
            <div class="annex-content">
              <template v-if="file.name.search('.docx') > -1">
                <i class="annex-word icon-word2 iconfont"></i>
              </template>
              <template v-if="file.name.search('.pdf') > -1">
                <i class="annex-word icon-format-pdf iconfont"></i>
              </template>
              {{ file.name }}
              <span class="el-upload-list__item-actions">
                <span v-if="!disabled" class="el-upload-list__item-delete" @click="onRemove(file)">
                  <el-icon><Delete /></el-icon>
                </span>
              </span>
            </div>
          </template>
        </template>
        <template #tip>
          <div class="upload-tip" v-if="tip && props.limit !== fileLists.length">
            建议（{{ tip }})
          </div>
        </template>
      </el-upload>
    </div>
    <template v-if="require">
      <div class="error-tip" v-if="!props.vaild">{{ message }}</div>
    </template>
    <template v-if="isExceed">
      <div class="error-tip">超出范围,请重新上传</div>
    </template>
    <el-dialog v-model="dialogVisible">
      <img w-full :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
    <el-dialog
      v-model="shearVisible"
      title="剪切图片"
      :show-close="false"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
    >
      <Cropper
        :imgObj="currentImgObj"
        :config="props.shearConfig"
        @cancle="shearVisible = false"
        @confirm="onCropperSave"
      />
    </el-dialog>
  </div>
</template>
<script setup>
import { onMounted, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Delete, Plus, ZoomIn, Crop } from '@element-plus/icons-vue'
// import { deepCopyData } from '@/utils'
import Cropper from './cropper.vue'

const props = defineProps({
  shear: { //  是否开启上传剪切
    type: Boolean,
    default: () => false
  },
  shearConfig: { //  剪切配置，具体配置查看cropper 组件
    type: Object,
    default: () => { }
  },
  vaild: { //  默认图片校验通过
    type: Boolean,
    default: () => true
  },
  require: { //  是否是必填项
    type: Boolean,
    default: () => true
  },
  message: { //  不为空提示
    type: String,
    default: () => '文件不能为空'
  },
  tip: { //  tip 提示
    type: String,
    default: () => ''
  },
  fileLists: {
    type: Array,
    default: () => []
  },
  limit: { //  多图上传，最多允许几张图片
    type: Number,
    default: () => 2
  },
  multiple: {
    type: Boolean,
    default: () => true
  },
  accept: {
    type: String,
    default: () => 'image/*'
  },
  showFileList: {
    type: Boolean,
    default: () => false
  },
  drag: {
    type: Boolean,
    default: () => true
  },
  maxSize: { //  最大size,10M
    type: Number,
    default: () => 10
  },
  disabled: { // 是否禁止
    type: Boolean,
    default: () => false
  }
})
const fileArr = ref([])
const imgValid = ref(true) //  图片校验是否通过
const uploadRef = ref(null)
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const emits = defineEmits(['update:fileLists'])
const shearVisible = ref(false)// 剪切弹框
const currentImgObj = ref(null) // 当前上传的图片
const isExceed = ref(false)
const fileCropperArr = ref([]) // 剪切的图
watch(() => props.fileLists, (newV, oldV) => {
  // fileArr.value = deepCopyData(props.fileLists)
  fileArr.value = props.fileLists
  imgValid.value = fileArr.value.length > 0
}, { immediate: true, deep: true })
onMounted(() => {
  fileCropperArr.value = []
})
/**
 * 清空剪切的数组
 */
const clearShearArr = () => {
  fileCropperArr.value = []
}
defineExpose({ clearShearArr })
/**
 * 剪切保存
 */
const onCropperSave = (res) => {
  // const newFileArr = deepCopyData(fileArr.value)
  const newFileArr = fileArr.value
  fileArr.value = []
  const reg = /blob:(\S*)/
  for (const item of newFileArr) {
    if (!reg.test(item.url)) { // 服务器图片,代表着图片没有变化
      fileArr.value.push(item)
    }
  }
  fileCropperArr.value.push(res)
  console.log('fileCropperArrSave=', fileCropperArr.value)
  shearVisible.value = false
  for (const item of fileCropperArr.value) {
    const newDate = Date.now()
    const raw = new File([item.raw], item.name, { type: 'image/png', lastModified: newDate })
    raw.uid = item.uid

    const newImgObj = {
      name: item.name,
      url: item.url,
      raw,
      status: props.imgObj?.status || 'ready',
      percentage: props.imgObj?.percentage || 0,
      size: raw.size,
      uid: raw.uid
    }
    fileArr.value.push(newImgObj)
  }
  exportList()
}
/**
 * 打开剪切
 */
const onCropper = (file) => {
  // currentImgObj.value = file
  shearVisible.value = true
}
/**
 * 超出范围
 */
const onExceed = () => {
  isExceed.value = true
  setTimeout(() => {
    isExceed.value = false
  }, 3000)
}
/**
   * 预览
   */
const onImgPreview = (file) => {
  dialogImageUrl.value = file.url
  dialogVisible.value = true
}
/**
   * 删除
   */
const onRemove = (file) => {
  const reg = /blob:(\S*)/
  let index
  if (!reg.test(file.url)) { // 服务器图片
    index = fileArr.value.findIndex(item => item.id === file.id)
  } else { //  上传的图片以blob: 开头
    index = fileArr.value.findIndex(item => item.uid === file.uid)
  }
  if (index > -1) { // 删除
    fileArr.value.splice(index, 1)
  }
  // console.log('删除', index)
  if (props.shear) { // 剪切
    const sIndex = fileCropperArr.value.findIndex(item => item.uid === file.uid)
    // console.log('剪切的图片删除', sIndex)
    if (sIndex > -1) {
      fileCropperArr.value.splice(sIndex, 1)
    }
  }
  // if (reg.test(file.url)) { // 上传的图片
  //   if (!props.shear) {
  //     uploadRef.value.handleRemove(file)
  //   }
  // }
  // console.log('fileCropperArrDel=', fileCropperArr)
  exportList()
}
/**
   * 上传
   */
const onChange = (file, fileList) => {
  console.log('onChangefile', file, fileCropperArr.value)
  if (props.shear && props.accept.search('image') > -1) { // 开启剪切仅支持图片剪切
    shearVisible.value = true
    currentImgObj.value = file
  } else {
    const files = file.raw
    const isLt2M = files.size / 1024 / 1024 < props.maxSize
    if (!isLt2M) {
      ElMessage.error(`只能上小于${props.maxSize}M的文件`)
    } else {
      fileArr.value.push(file)
    }
    exportList()
  }
}
/**
   * 抛出list
   */
const exportList = () => {
  imgValid.value = fileArr.value.length > 0
  console.log('exportList', fileArr.value, imgValid.value)

  emits('update:fileLists', fileArr.value)
  emits('update:vaild', imgValid.value)
}
const bufToFile = (buf, filename) => {
  return new File([buf], filename, { type: 'image/png', lastModified: Date.now() })
}
</script>
<style lang="scss" scoped>
.upload-container {
  .upload-content {
    @include flexLayout($vertical: flex-end);
    .upload-tip {
      font-size: 12px;
      margin-left: 5px;
    }
    .upload-file {
      &.no-multiple,
      &.limit {
        ::v-deep .el-upload-list__item ~ .el-upload {
          display: none;
        }
      }
    }
  }
  .error-tip {
    font-size: 12px;
    color: #f56c6c;
    margin-top: 10px;
  }
  .annex-content {
    margin-top: 14px;
    font-size: 20px;
    .annex-word {
      font-size: 24px;
      color: #409eff;
    }
  }
}
</style>
